#include <stdio.h>
#include <new>
#include <crtdbg.h>

#include "toolbox_interchange.hpp"
#include "rdxsupport.hpp"
#include "../tdp2/tdp2_visualresources.hpp"
#include "../../rdx/src/rdx/rdx_objectmanagement.hpp"
#include "../../rdx/src/rdx/rdx_interpret.hpp"

ToolResources toolResources;

using namespace RDX;
using namespace RDX::Programmability;
using namespace RDX::ObjectManagement;

int RPhoton_Main();
int RDXToBin_Main();
int ExportSource_Main();
int MergePL_Main();

int RDX_DECL_API DummyCallback(OperationContext *ctx, ObjectManagement::IObjectManager *objm, const Method *m, RuntimeThread *thread, RuntimeStackValue *prv)
{
	return 0;
}

struct FallbackTypeHost : public INativeTypeHost
{
	void SetTypeProperties(IObjectManager *objm, Programmability::StructuredType *st) const
	{
	}

	Programmability::NativeCallback HookMethod(const Programmability::String *str) const
	{
		return DummyCallback;
	}
} fallbackTypeHost;

using namespace TDP::Math;

#include "../tdp2/tdp2_random.hpp"

int main(int argc, const char **argv)
{
	if(argc < 2)
	{
		fprintf(stderr, "Syntax: rtoolbox <tool> <args>");
		exit(-1);
	}

	RDXSupport::SimpleRDXSupportPackage supportPkg;
	toolResources.supportPkg = &supportPkg;

	RDX_Initialize();
	RDXSupport::GetRDXSupportPackage(&supportPkg);

	toolResources.argc = argc;
	toolResources.argv = argv;

	const RDX::ObjectManagement::INativeTypeHost *typeHosts[] =
	{
		RDX_GetNumericTypesPlugin(),
		TDP::Resources::GetVisualResourcesPluginDetached(),
		&fallbackTypeHost,
		NULL
	};

	RDX::CombinedNativeTypeHost plug_myTypeHost(typeHosts);
	
	RDX::Programmability::ICodeProvider *codeProvider = RDX_CreateInterpreterCodeProvider(&supportPkg.alloc, NULL, 0);
	RDX::ObjectManagement::IObjectManager *objm = RDX_CreateObjectManager(&supportPkg.alloc, &plug_myTypeHost, codeProvider);
	
	int rv = -1;
	{
		RDX::OperationContext ctx(objm);

		bool rdxTextFirst = (argc >= 3 && !strcmp(argv[2], "-rdxtextfirst"));

		RDX::Security::ZonePolicyPackageHost zph(&ctx, objm, supportPkg.fs, rdxTextFirst);
		
		printf("------------- RToolbox ------------- \n");
		printf("Loading zone policy...\n");

		RDXSupport::LoadZonePolicy(&ctx, objm, &zph, RDX_STATIC_STRING("TDPTools.zonepolicy"));
		ctx.Deaden();	// Don't use this any more, but we still need zph

		toolResources.supportPkg = &supportPkg;
		toolResources.typeHost = &plug_myTypeHost;
		toolResources.pkgHost = &zph;
		toolResources.objm = objm;
		
		printf("Running tool %s...\n", argv[1]);

		if(!strcmp(argv[1], "rphoton"))
			rv = RPhoton_Main();
		else if(!strcmp(argv[1], "rdxtobin"))
			rv = RDXToBin_Main();
		else if(!strcmp(argv[1], "exportsource"))
			rv = ExportSource_Main();
		else if(!strcmp(argv[1], "mergepl"))
			rv = MergePL_Main();
		else
		{
			rv = -1;
			fprintf(stderr, "Unknown tool");
		}
	}	// Policy should drop scope now

	objm->Shutdown();
	codeProvider->Shutdown();

	return rv;
}
